package com.logger.common;

import java.io.OutputStream;
import java.io.Reader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * 工具类
 * Created by chenxunlin01 on 2016/1/16.
 */

public class Utils {

    /**
     * 换行符
     */
    public static final String LINE_RETURN = System.getProperty("line.separator");


    /**
     * 加载类
     * @param className
     * @return
     */
    public static Class<?> loadCLass(String className) {
        try {
            return Class.forName(className);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }

    /**
     * 实例化类
     * @param clazz
     * @return
     */
    public static Object newInstance(Class<?> clazz) {
        try {
            Constructor<?> cst = clazz.getConstructor();
            if (cst != null) {
                return cst.newInstance();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 关闭流
     * @param reader
     */
    public static void closeIO(Reader reader) {
        try {
            if (reader != null) {
                reader.close();
            }
        } catch (Exception e) {
        }
    }

    /**
     * 关闭流
     * @param os
     */
    public static void closeIO(OutputStream os) {
        try {
            if (os != null) {
                os.close();
            }
        } catch (Exception e) {
        }
    }

    /**
     *  反射执行方法
     * @param obj
     * @param name
     * @return
     */
    public static Object getGetMethodObject(Object obj, String name) {
        Method method = getGetMethod(obj.getClass(), name);
        if (method == null) {
            return null;
        }
        try {
            return method.invoke(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取get方法对象
     * @param clazz
     * @param name
     * @return
     */
    public static Method getGetMethod(Class<?> clazz, String name) {
        StringBuilder buf = new StringBuilder();
        buf.append("get");
        buf.append(name.substring(0, 1).toUpperCase());
        buf.append(name.substring(1));
        try {
            return clazz.getMethod(buf.toString());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取set方法对象
     * @param clazz
     * @param name
     * @param params
     * @return
     */
    public static Method getSetMethod(Class<?> clazz, String name, Class<?>[] params) {
        StringBuilder buf = new StringBuilder();
        buf.append("set");
        buf.append(name.substring(0, 1).toUpperCase());
        buf.append(name.substring(1));
        try {
            return clazz.getMethod(buf.toString(), params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取set方法对象
     * @param clazz
     * @param name
     * @return
     */
    public static Method getSetMethod(Class<?> clazz, String name) {
        StringBuilder buf = new StringBuilder();
        buf.append("set");
        buf.append(name.substring(0, 1).toUpperCase());
        buf.append(name.substring(1));
        try {
            String methodName = buf.toString();
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    return method;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 反射注入属性值
     * @param obj
     * @param name
     * @param s
     * @return
     */
    public static boolean setStringValue(Object obj, String name, String s) {
        StringBuilder buf = new StringBuilder();
        buf.append("set");
        buf.append(name.substring(0, 1).toUpperCase());
        buf.append(name.substring(1));
        try {
            Method method = getSetMethod(obj.getClass(), name);
            if (method != null) {
                Class<?>[] paramTypes = method.getParameterTypes();
                if (paramTypes == null || paramTypes.length == 0) {
                    return false;
                }
                return setMethodValue(obj, method, paramTypes[0], s);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 注入属性值
     * @param obj
     * @param method
     * @param paramType
     * @param val
     * @return
     */
    public static boolean setMethodValue(Object obj, Method method, Class<?> paramType, String val) {
        Object vobject = convertStringObject(paramType, val);
        if (vobject == null) {
            return false;
        }
        try {
            method.invoke(obj, vobject);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     *  字符串解析为对象
      * @param paramType
     * @param val
     * @return
     */
    public static Object convertStringObject(Class<?> paramType, String val) {
        try {
            if (int.class.equals(paramType) || Integer.class.equals(paramType)) {
                return Integer.parseInt(val);
            } else if (short.class.equals(paramType) || Short.class.equals(paramType)) {
                return Short.parseShort(val);
            } else if (boolean.class.equals(paramType) || Boolean.class.equals(paramType)) {
                return Boolean.parseBoolean(val);
            } else if (byte.class.equals(paramType) || Byte.class.equals(paramType)) {
                return Byte.parseByte(val);
            } else if (long.class.equals(paramType) || Long.class.equals(paramType)) {
                return Long.parseLong(val);
            } else if (double.class.equals(paramType) || Double.class.equals(paramType)) {
                return Double.parseDouble(val);
            } else if (float.class.equals(paramType) || Float.class.equals(paramType)) {
                return Float.parseFloat(val);
            } else if (char.class.equals(paramType)) {
                return val.charAt(0);
            } else if (String.class.equals(paramType)) {
                return val;
            } else {
                Class<?> clazz = loadCLass(val);
                if (clazz == null) {
                    throw new Exception("Cannot instance object class " + val);
                }
                return newInstance(clazz);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
